/**
 * Created by XHL on 2022-07-26.
 */

#include <TheMap.h>

namespace entity {
	TheMap::TheMap(const int &time_, const int &size)
			: m_size(size), m_time(time_) {
		this->m_shrunk = false;
		this->m_tankA = nullptr;
		this->m_tankB = nullptr;
		this->draw();
	}

	void TheMap::response() {
		/** map size shrinks down by 2 every 16 turns */
		this->m_shrunk = global::game_round >> 4;
		this->m_size -= this->m_shrunk << 1;
		global::game_round -= this->m_shrunk << 4;
		this->m_time += this->m_shrunk;
		/** map location (might) changes */
		global::left_top += { this->m_shrunk << 1, this->m_shrunk };
		/** draw map */
		this->draw();
		/** modify hp */
		this->modify_hp();
	}

	void TheMap::draw() const {
		if (this->m_shrunk) {
			system("cls");
			this->m_tankA->display_self(m_tankA->get_location());
			this->m_tankB->display_self(m_tankB->get_location());
		}
		/** draw horizontal line */
		entity::TheMap::draw_horizontal(global::left_top, this->m_size + 2);
		Location delta_y{ 0, this->m_size + 1 };
		entity::TheMap::draw_horizontal(global::left_top + delta_y, this->m_size + 2);
		/** draw vertical line */
		entity::TheMap::draw_vertical(global::left_top, this->m_size);
		Location delta_x{ (this->m_size + 1) << 1, 0 };
		entity::TheMap::draw_vertical(global::left_top + delta_x, this->m_size);
	}

	[[nodiscard]] const Tank *TheMap::getTankA() const {
		return this->m_tankA;
	}

	[[nodiscard]] const Tank *TheMap::getTankB() const {
		return this->m_tankB;
	}

	[[nodiscard]] int TheMap::get_size() const {
		return this->m_size;
	}

	void TheMap::set_size(int size) {
		this->m_size = size;
	}

	void TheMap::draw_horizontal(const Location &pos, const int &length) {
		handle::set_cursor_location(pos);
		std::cout << "\033[45m";
		for (int i = 0; i < length; ++i) {
			std::cout << "  ";
		}
		std::cout << "\033[0m";
	}

	void TheMap::draw_vertical(Location pos, const int &length) {
		handle::set_cursor_location(pos);
		for (int i = 0; i < length; ++i) {
			handle::set_cursor_location(pos += { 0, 1 });
			std::cout << "\033[45m  \033[0m";
		}
	}

	void TheMap::set_player_A(Tank *mTankA) {
		this->m_tankA = mTankA;
	}

	void TheMap::set_player_B(Tank *mTankB) {
		this->m_tankB = mTankB;
	}

	void TheMap::modify_hp() {
		Location loc_a = this->m_tankA->get_location();
		Location loc_b = this->m_tankB->get_location();
		if (loc_a.get_x() < global::left_top.get_x() ||
			loc_a.get_y() < global::left_top.get_y() ||
			loc_a.get_x() > global::left_top.get_x() + this->m_size ||
			loc_a.get_y() > global::left_top.get_y() + this->m_size) {
			this->m_tankA->set_hp(this->m_tankA->get_hp() - 1);
		}
		if (loc_b.get_x() < global::left_top.get_x() ||
			loc_b.get_y() < global::left_top.get_y() ||
			loc_b.get_x() > global::left_top.get_x() + this->m_size ||
			loc_b.get_y() > global::left_top.get_y() + this->m_size) {
			this->m_tankB->set_hp(this->m_tankB->get_hp() - 1);
		}
	}
} // entity